﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;


namespace AnaViewer
{
    /// <summary>
    /// 提供基类。
    /// 绘制时：Paint() 方法将按照实际位置绘制；
    /// OnPaint() 方法总是绘制 (0,0,width,height) 区域。
    /// </summary>
    public class ViewBase : IDisposable
    {
        /// <summary>
        /// 标识 图片 无效。即需要更新。
        /// </summary>
        bool isInvalid = true;
        /// <summary>
        /// 语录句子的图片。
        /// </summary>
        Bitmap saying;

        //protected Control owner = null;
        //public ViewBase(Control owner)
        //{
        //    this.owner = owner;
        //}
        public ViewBase()
        {
        }

        /// <summary>
        /// 改变窗体大小，则需要同时改变图片 scr 的大小。
        /// </summary>
        protected virtual void OnResize(EventArgs e)
        {
            this.Invalidate();
        }
        public virtual void OnMouseMove(MouseEventArgs e)
        {
        }

        protected Rectangle bounds = Rectangle.Empty;
        /// <summary>
        /// 真正绘制占用的区域。
        /// </summary>
        public Rectangle Bounds
        {
            get { return bounds; }
            set
            {
                if (bounds == value)
                    return;
                bool resized = (bounds.Size != value.Size);
                bounds = value;
                if(resized)
                    OnResize(new EventArgs());
            }
        }
        public Point Location
        {
            get { return bounds.Location; }
            set
            {
                if (bounds.Location == value)
                    return;
                bounds.Location = value;
            }
        }
        public Size Size
        {
            get { return bounds.Size; }
            set
            {
                if (bounds.Size == value)
                    return;

                bounds.Size = value;
                OnResize(new EventArgs());
            }
        }
        public int X
        {
            get { return bounds.X; }
            set { bounds.X = value; }
        }
        public int Y
        {
            get { return bounds.Y; }
            set { bounds.Y = value; }
        }


        /// <summary>
        /// 在控件样式更改时发生。
        /// </summary>
        public event EventHandler StyleChanged;
        /// <summary>
        /// 引发 StyleChanged 事件。
        /// </summary>
        /// <param name="e">包含事件数据的 System.EventArgs。</param>
        protected virtual void OnStyleChanged(EventArgs e)
        {
            if (StyleChanged != null)
                StyleChanged(this, e);
        }

        /// <summary>
        /// 重绘 格言 图片。
        /// </summary>
        private void FreshSayingBmp()
        {
        }

        public void Paint(PaintEventArgs e)
        {
            if (saying == null || isInvalid)
            {//需要重绘图片。

                if (saying == null || saying.Size != bounds.Size)
                { //更改图片的大小。
                    if (saying != null)
                    {
                        saying.Dispose();
                        saying = null;
                    }
                    if (bounds.Width > 0 && bounds.Height > 0)
                        saying = new Bitmap(bounds.Width, bounds.Height);
                    else
                        saying = new Bitmap(512, 600);
                }

                using (Graphics g = Graphics.FromImage(saying))
                {
                    g.Clear(backColor);
                    OnPaint(new PaintEventArgs(g, new Rectangle(0, 0, saying.Width, saying.Height)));
                    foreach (ViewBase view in Views)
                        view.Paint(new PaintEventArgs(g, view.bounds));
                }

                isInvalid = false;
            }
            //图片有效
            e.Graphics.DrawImageUnscaledAndClipped(saying, bounds);
        }
        protected virtual void OnPaint(PaintEventArgs e)
        {
        }

        List<ViewBase> Views = new List<ViewBase>();

        /// <summary>
        /// 使控件的整个图面无效并导致重绘控件。
        /// </summary>
        public void Invalidate()
        {
            Invalidate(false);
        }
        /// <summary>
        /// 使控件的特定区域无效并向控件发送绘制消息。还可以使分配给该控件的子控件无效。
        /// </summary>
        /// <param name="invalidateChildren">若要使控件的子控件无效，则为 true；否则为 false。</param>
        public void Invalidate(bool invalidateChildren)
        {
            if (invalidateChildren)
            {
                foreach (ViewBase view in Views)
                {
                    view.Invalidate(true);
                }
            }
            if (!isInvalid)//第一次请求刷新
            {
                isInvalid = true;
                OnInvalidated(new InvalidateEventArgs(this.bounds));
            }
        }
        /// <summary>
        /// 在控件的显示需要重绘时发生。
        /// </summary>
        public event InvalidateEventHandler Invalidated;
        /// <summary>
        /// 引发 System.Windows.Forms.Control.Invalidated 事件。
        /// </summary>
        /// <param name="e">包含事件数据的 System.Windows.Forms.InvalidateEventArgs。</param>
        protected virtual void OnInvalidated(InvalidateEventArgs e)
        {
            if (Invalidated != null)
                Invalidated(this, e);
        }

        protected Color backColor = Color.Transparent;
        /// <summary>
        /// 描边的颜色。
        /// </summary>
        public Color BackColor
        {
            get { return backColor; }
            set { backColor = value; OnStyleChanged(new EventArgs()); this.Invalidate(); }
        }
        protected Color foreColor = Color.Black;
        public Color ForeColor
        {
            get { return foreColor; }
            set { foreColor = value; this.Invalidate(); }
        }

        Font font = Control.DefaultFont;
        public Font Font
        {
            get { return font; }
            set { font = value; this.Invalidate(); }
        }

        /// <summary>
        /// 是否显示。
        /// </summary>
        bool visible = false;
        public bool Visible
        {
            get { return visible; }
            set
            {
                if (visible == value)
                    return;

                visible = value;
                OnVisibleChanged(new EventArgs());
            }
        }
        public event EventHandler VisibleChanged;
        protected virtual void OnVisibleChanged(EventArgs e)
        {
            if (VisibleChanged != null)
                VisibleChanged(this, e);
        }




        #region IDisposable 成员

        public virtual void Dispose()
        {
            foreach (ViewBase view in Views)
                view.Dispose();
        }

        #endregion
    }
}
